// 对象的扩展

// 1. 属性简洁表示法
/*
let name = "jayjun";
let age = 18;

let user = {
    name,
    age,
    study() {
        console.log(this.name + "正在学习")
    }
}

user.study();
*/

// 2. 属性名表达式
let name = "jayjun";
let age = 18;
let s = "school";

let user = {
    name,
    age,
    [s]: "家里蹲大学",
    study() {
        console.log(this.name + "正在" + this.school + "学习")
    }
}

user.study();

// 3. Object.is()：判断两个对象是否相等
console.log(Object.is(2, "2"));     // false

console.log(Object.is(NaN, NaN));   // true
console.log(NaN == NaN);            // false

console.log(Object.is(+0, -0));     // false


let obj1 = {
    name: "jayjun",
    age: 18
};

let obj2 = {
    name: "jayjun",
    age: 18
};

console.log(Object.is(obj1, obj2)); // false
console.log(obj1 == obj2);          // false

let obj3 = obj1;

console.log(Object.is(obj1, obj3)); // true
console.log(obj1 == obj3);          // true

// 4. Object.assign()：合并对象
// 语法：Object.assign(target, ...sources)
// 参数target：必需，目标对象，接收源对象属性的对象，也就是修改后的返回值
// 参数sources：可选，源对象，包含将被合并的属性
// 返回值：目标对象

let target = {
    a: 1,
    b: 2
}

let source = {
    b: 3,
    c: 4
}

let returnedTarget = Object.assign(target, source);

console.log(target);

console.log(returnedTarget);

// 如果目标对象不是对象，则会自动转换为对象。
console.log(Object.assign(1)); // {1}
console.log(Object.assign(1, {a: 2})); // {1, a: 2}

// 如果对象属性具有多层嵌套，会怎么样？

let target2 = {
    a: {
        b: 1,
        c: 2,
        g: 6
    },
    e: 4,
    f: 5
}

let source2 = {
    a: {
        b: 1
    },
    e: 2,
    f: 3
}

Object.assign(target2, source2);

console.log(target2);

// 你会发现，c 和 g 属性消失了

// 注意：Object.assign() 对于引用类型属于浅拷贝。

// 5. in

let b = {
    a: 1,
    c: 2
}

console.log('a' in b); // true

let arr = [1, 2, 3];
console.log(2 in arr); // true

// 6. 对象的遍历方式

// 1. for in

let person = {
    name: "jayjun",
    age: 18,
    school: "家里蹲大学"
};

for(let key in person) {
    console.log(key, person[key]);
}

// 2. Object.keys()

Object.keys(person).forEach(key => {
    console.log(key, person[key]);
})